using System;
using System.Linq;
using System.Windows.Forms;
using FireStarter.Base;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Logic;
using Firestarter.DB.Schema.Test.BO.TestUtils;
using FireStarterModeller.BO;
using Firestarter.DB.Schema.UI;
using FireStarterModeller.Test;
using FireStarterModeller.UI;
using Habanero.Base;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using Habanero.Testability;
using NUnit.Framework;
using Firestarter.DB.Schema.Test.Logic;
using TreeViewController=Habanero.Faces.Base.TreeViewController;

namespace Firestarter.DB.Schema.Test.UI
{
    // ReSharper disable InconsistentNaming
    [TestFixture]
    public class TestDatabaseInfoChangesControl: TestBase
    {
        [Test]
        public void Test_Construct_ShouldSetupTreeViewToSuppressDoubleClick()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            //---------------Test Result -----------------------
            TreeViewWin treeView = (TreeViewWin) databaseInfoChangesControl.TreeViewController.TreeView;
            Assert.IsNotNull(treeView);
            Assert.IsTrue(treeView.SuppressDoubleClickEvent);
        }

        [Test]
        public void Test_DatabaseInfo()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase= new DBDatabase();
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            Assert.AreSame(dbDatabase, databaseInfoChangesControl.Database);
        }

        [Test]
        public void Test_NodeImages()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBColumn updatedDBColumn = new DBColumn("UpdatedColumn") { PendingChangeType = ChangeType.Update };
            dbTable.Columns.Add(updatedDBColumn);
            DBColumn addedDBColumn = new DBColumn("AddedColumn") { PendingChangeType = ChangeType.Add };
            dbTable.Columns.Add(addedDBColumn);
            DBColumn deletedDBColumn = new DBColumn("DeletedColumn") { PendingChangeType = ChangeType.Delete };
            dbTable.Columns.Add(deletedDBColumn);
            DBColumn unchangedDBColumn = new DBColumn("UnchangedColumn") { PendingChangeType = ChangeType.None };
            dbTable.Columns.Add(unchangedDBColumn);

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions -------------
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            AssertColumnImageKeyCorrect("Change", treeViewController, dbDatabase);
            AssertColumnImageKeyCorrect("Change", treeViewController, dbTable);
            AssertColumnImageKeyCorrect("Change", treeViewController, updatedDBColumn);
            AssertColumnImageKeyCorrect("Add", treeViewController, addedDBColumn);
            AssertColumnImageKeyCorrect("Delete", treeViewController, deletedDBColumn);
            AssertColumnImageKeyCorrect("None", treeViewController, unchangedDBColumn);
        }

        [Test]
        public void Test_NodeImages_ChangeWhenBoUpdated()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.None };
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            databaseInfoChangesControl.Database = dbDatabase;
            //-------------Assert Preconditions -------------
            AssertColumnImageKeyCorrect("None", treeViewController, dbDatabase);
            //---------------Execute Test ----------------------
            dbDatabase.PendingChangeType = ChangeType.Update;
            //---------------Test Result -----------------------
            AssertColumnImageKeyCorrect("Change", treeViewController, dbDatabase);
        }

        private static void AssertColumnImageKeyCorrect(string expectedImageKey, TreeViewController treeViewController, IBusinessObject businessObject)
        {
            ImageList imageList = ((TreeView)treeViewController.TreeView).ImageList;
            int expectedImageIndex = imageList.Images.IndexOfKey(expectedImageKey);
            Assert.AreEqual(expectedImageIndex, treeViewController.GetBusinessObjectTreeNode(businessObject).SelectedImageIndex);
            Assert.AreEqual(expectedImageIndex, treeViewController.GetBusinessObjectTreeNode(businessObject).ImageIndex);
        }

        [Test]
        public void Test_NodeText_Table()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(dbTable);
            Assert.AreEqual(dbTable.TableName, treeNode.Text);
        }

        [Test]
        public void Test_NodeText_Column()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBColumn updatedDBColumn = new DBColumn("UpdatedColumn") { PendingChangeType = ChangeType.Update };
            dbTable.Columns.Add(updatedDBColumn);

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(updatedDBColumn);
            Assert.AreEqual(updatedDBColumn.ColumnName, treeNode.Text);
        }

        [Test]
        public void Test_NodeText_PrimaryKey()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBColumn primaryKeyColumn = dbTableBuilder.AddPrimaryKeyColumn().Column;
            DBPrimaryKey primaryKey = dbTable.PrimaryKeyDB;
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(primaryKeyColumn);
            Assert.IsNotNull(primaryKey);
            Assert.AreEqual(1, primaryKey.Columns.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(primaryKey);
            Assert.AreEqual("Primary", treeNode.Text);
        }

        [Test]
        public void Test_NodeText_PrimaryKeyColumn()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBColumn primaryKeyColumn = dbTableBuilder.AddPrimaryKeyColumn().Column;
            DBPrimaryKey primaryKey = dbTable.PrimaryKeyDB;
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(primaryKeyColumn);
            Assert.IsNotNull(primaryKey);
            Assert.AreEqual(1, primaryKey.Columns.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(primaryKeyColumn);
            Assert.AreEqual(primaryKeyColumn.ColumnName, treeNode.Text);
        }

        [Test]
        public void Test_NodeText_UniqueKey()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBColumn uniqueKeyColumn = dbTableBuilder.AddUniqueKeyColumn("ExistingAKColumn");
            DBKey uniqueKey = dbTable.Keys[0];
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(uniqueKeyColumn);
            Assert.IsNotNull(uniqueKey);
            Assert.AreEqual(1, uniqueKey.Columns.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(uniqueKey);
            Assert.AreEqual(uniqueKey.KeyName, treeNode.Text);
        }

        [Test]
        public void Test_NodeText_UniqueKeyColumn()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBColumn uniqueKeyColumn = dbTableBuilder.AddUniqueKeyColumn("ExistingAKColumn");
            DBKey uniqueKey = dbTable.Keys[0];
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(uniqueKeyColumn);
            Assert.IsNotNull(uniqueKey);
            Assert.AreEqual(1, uniqueKey.Columns.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(uniqueKeyColumn);
            Assert.AreEqual(uniqueKeyColumn.ColumnName, treeNode.Text);
        }

        [Test]
        public void Test_NodeText_ForeignKey()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTable dbParentTable = new DBTable("MyLookupTable") { PendingChangeType = ChangeType.Update };
            DBTableBuilder dbParentTableBuilder = new DBTableBuilder(dbParentTable);
            dbParentTableBuilder.AddPrimaryKeyColumn();
            dbDatabase.Tables.Add(dbParentTable);

            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBForeignKey foreignKey = dbTableBuilder.AddForeignKey("MyForeignKey", dbParentTable);

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(foreignKey);
            Assert.IsNotNull(foreignKey.ParentTable);
            Assert.IsNotNull(foreignKey.RelatedTable);
            Assert.AreEqual(1, dbTable.ForeignKeys.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(foreignKey);
            Assert.AreEqual(foreignKey.ForeignKeyName + " (" + foreignKey.RelatedTable.TableName + ")", treeNode.Text);
        }

        [Test]
        public void Test_NodeText_ForeignKeyColumn()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTable dbLookupTable = new DBTable("MyLookupTable") { PendingChangeType = ChangeType.Update };
            DBTableBuilder lookupTableBuilder = new DBTableBuilder(dbLookupTable);
            DBColumn lookupTablePrimaryKeyColumn = lookupTableBuilder.AddPrimaryKeyColumn().Column;
            dbDatabase.Tables.Add(dbLookupTable);

            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBForeignKey dbForeignKey = dbTableBuilder.AddForeignKey("MyForeignKey", dbLookupTable);
            DBForeignKeyColumn foreignKeyColumn = dbForeignKey.ForeignKeyColumns[0];
            DBColumn foreignKeyIDColumn = foreignKeyColumn.ParentColumn;
            foreignKeyIDColumn.ColumnName = "MyForeignKeyIDColumn";
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(dbForeignKey);
            Assert.AreEqual(1, dbForeignKey.ForeignKeyColumns.Count);
            Assert.IsNotNull(foreignKeyColumn);
            Assert.IsNotNull(foreignKeyIDColumn);
            Assert.IsNotNull(lookupTablePrimaryKeyColumn);
            Assert.AreEqual(1, dbTable.ForeignKeys.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(foreignKeyColumn);
            Assert.AreEqual(string.Format("{0} -> {1}", foreignKeyIDColumn.ColumnName, lookupTablePrimaryKeyColumn.ColumnName), treeNode.Text);
        }

        [Test]
        public void Test_NodeText_ForeignKeyColumn_WhenRelatedColumnNull()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTable dbLookupTable = new DBTable("MyLookupTable") { PendingChangeType = ChangeType.Update };
            DBTableBuilder lookupTableBuilder = new DBTableBuilder(dbLookupTable);
            DBColumn lookupTablePrimaryKeyColumn = lookupTableBuilder.AddPrimaryKeyColumn().Column;
            dbDatabase.Tables.Add(dbLookupTable);

            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBForeignKey dbForeignKey = dbTableBuilder.AddForeignKey("MyForeignKey", dbLookupTable);
            DBForeignKeyColumn foreignKeyColumn = dbForeignKey.ForeignKeyColumns[0];
            DBColumn foreignKeyIDColumn = foreignKeyColumn.ParentColumn;
            foreignKeyIDColumn.ColumnName = "MyForeignKeyIDColumn";
            foreignKeyColumn.RelatedColumn = null;
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(dbForeignKey);
            Assert.AreEqual(1, dbForeignKey.ForeignKeyColumns.Count);
            Assert.IsNotNull(foreignKeyColumn);
            Assert.IsNotNull(foreignKeyIDColumn);
            Assert.IsNotNull(lookupTablePrimaryKeyColumn);
            Assert.AreEqual(1, dbTable.ForeignKeys.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(foreignKeyColumn);
            Assert.AreEqual(string.Format("{0} -> {1}", foreignKeyIDColumn.ColumnName, "(Unspecified)"), treeNode.Text);
        }

        [Test]
        public void Test_NodeText_ForeignKeyColumn_WhenParentColumnNull()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTable dbLookupTable = new DBTable("MyLookupTable") { PendingChangeType = ChangeType.Update };
            DBTableBuilder lookupTableBuilder = new DBTableBuilder(dbLookupTable);
            DBColumn lookupTablePrimaryKeyColumn = lookupTableBuilder.AddPrimaryKeyColumn().Column;
            dbDatabase.Tables.Add(dbLookupTable);

            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBForeignKey dbForeignKey = dbTableBuilder.AddForeignKey("MyForeignKey", dbLookupTable);
            DBForeignKeyColumn foreignKeyColumn = dbForeignKey.ForeignKeyColumns[0];
            DBColumn foreignKeyIDColumn = foreignKeyColumn.ParentColumn;
            foreignKeyIDColumn.ColumnName = "MyForeignKeyIDColumn";
            foreignKeyColumn.ParentColumn = null;
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(dbForeignKey);
            Assert.AreEqual(1, dbForeignKey.ForeignKeyColumns.Count);
            Assert.IsNotNull(foreignKeyColumn);
            Assert.IsNotNull(foreignKeyIDColumn);
            Assert.IsNotNull(lookupTablePrimaryKeyColumn);
            Assert.AreEqual(1, dbTable.ForeignKeys.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(foreignKeyColumn);
            Assert.AreEqual(string.Format("{0} -> {1}", "(Unspecified)", lookupTablePrimaryKeyColumn.ColumnName), treeNode.Text);
        }

        [Test]
        public void Test_NodeText_ForeignKeyColumn_WhenParentColumnNullAndRelatedColumnNull()
        {
            DBDatabase dbDatabase = new DBDatabase { PendingChangeType = ChangeType.Update };
            DBTable dbTable = new DBTable("MyUpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(dbTable);
            DBTable dbLookupTable = new DBTable("MyLookupTable") { PendingChangeType = ChangeType.Update };
            DBTableBuilder lookupTableBuilder = new DBTableBuilder(dbLookupTable);
            DBColumn lookupTablePrimaryKeyColumn = lookupTableBuilder.AddPrimaryKeyColumn().Column;
            dbDatabase.Tables.Add(dbLookupTable);

            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBForeignKey dbForeignKey = dbTableBuilder.AddForeignKey("MyForeignKey", dbLookupTable);
            DBForeignKeyColumn foreignKeyColumn = dbForeignKey.ForeignKeyColumns[0];
            DBColumn foreignKeyIDColumn = foreignKeyColumn.ParentColumn;
            foreignKeyIDColumn.ColumnName = "MyForeignKeyIDColumn";
            foreignKeyColumn.ParentColumn = null;
            foreignKeyColumn.RelatedColumn = null;
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController treeViewController = databaseInfoChangesControl.TreeViewController;
            //-------------Assert Preconditions ----------------
            Assert.IsNotNull(dbForeignKey);
            Assert.AreEqual(1, dbForeignKey.ForeignKeyColumns.Count);
            Assert.IsNotNull(foreignKeyColumn);
            Assert.IsNotNull(foreignKeyIDColumn);
            Assert.IsNotNull(lookupTablePrimaryKeyColumn);
            Assert.AreEqual(1, dbTable.ForeignKeys.Count);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode treeNode = treeViewController.GetBusinessObjectTreeNode(foreignKeyColumn);
            Assert.AreEqual(string.Format("{0} -> {1}", "(Unspecified)", "(Unspecified)"), treeNode.Text);
        }

        [Test]
        public void Test_Filter_Defaults()
        {
            //---------------Set up test pack-------------------
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            //---------------Test Result -----------------------
            IPanel panel = databaseInfoChangesControl.FilterPanel;
            Assert.IsNotNull(panel);
            Assert.AreEqual(4, panel.Controls.Count);
            AssertCheckBoxDetails("Unchanged", true, panel.Controls[0]);
            AssertCheckBoxDetails("Added", true, panel.Controls[1]);
            AssertCheckBoxDetails("Removed", true, panel.Controls[2]);
            AssertCheckBoxDetails("Updated", true, panel.Controls[3]);
        }

        private static void AssertCheckBoxDetails(string expectedText, bool checkedValue, IControlHabanero control)
        {
            Assert.IsInstanceOf(typeof(ICheckBox), control);
            ICheckBox checkBox = (ICheckBox) control;
            Assert.AreEqual(checkedValue, checkBox.Checked);
            Assert.AreEqual(expectedText, checkBox.Text);
        }

        [Test]
        public void Test_FilterUnchangedIsUnchecked_ShouldRemoveUnchangedTableFromTablesNodes()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable unchangedDBTable = dbDatabase.CreateUnchangedTable();
            DBTable addedDBTable = dbDatabase.CreateAddedTable();
            DBTable deletedDBTable = dbDatabase.CreateDeletedTable();
            DBTable updatedDBTable = dbDatabase.CreateUpdatedTable();

            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };

            ITreeView treeView = changesControl.TreeViewController.TreeView;
            ITreeNode tableInfosNode = treeView.Nodes[0].Nodes[0];
            ICheckBox checkbox = (ICheckBox)changesControl.FilterPanel.Controls[0];
            ITreeNodeCollection treeNodeCollection = tableInfosNode.Nodes;
            //-------------Assert Preconditions -------------
            Assert.AreEqual("Unchanged", checkbox.Text);
            Assert.AreEqual(true, checkbox.Checked);
            Assert.AreEqual(4, tableInfosNode.Nodes.Count);

            treeNodeCollection.AssertContainsTable(unchangedDBTable);
            //---------------Execute Test ----------------------
            checkbox.Checked = false;
            //---------------Test Result -----------------------
            Assert.AreEqual(3, tableInfosNode.Nodes.Count);
            treeNodeCollection.AssertNotContainsTable(unchangedDBTable);
        }

        [Test]
        public void Test_FilterAddedIsUnchecked_ShouldRemoveAddedTableFromTablesNodes()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable unchangedDBTable = dbDatabase.CreateUnchangedTable();
            DBTable addedDBTable = dbDatabase.CreateAddedTable();
            DBTable deletedDBTable = dbDatabase.CreateDeletedTable();
            DBTable updatedDBTable = dbDatabase.CreateUpdatedTable();

            var changesControl = new DatabaseInfoChangesControl {Database = dbDatabase};

            ITreeView treeView = changesControl.TreeViewController.TreeView;
            ITreeNode tableInfosNode = treeView.Nodes[0].Nodes[0];
            ICheckBox checkbox = (ICheckBox)changesControl.FilterPanel.Controls[1];
            ITreeNodeCollection treeNodeCollection = tableInfosNode.Nodes;
            //-------------Assert Preconditions -------------
            Assert.AreEqual("Added", checkbox.Text);
            Assert.AreEqual(true, checkbox.Checked);
            Assert.AreEqual(4, tableInfosNode.Nodes.Count);

            treeNodeCollection.AssertContainsTable(addedDBTable);
            //---------------Execute Test ----------------------
            checkbox.Checked = false;
            //---------------Test Result -----------------------
            Assert.AreEqual(3, tableInfosNode.Nodes.Count);          
            treeNodeCollection.AssertNotContainsTable(addedDBTable);
        }


        [Test]
        public void Test_FilterDeletedIsUnchecked_ShouldRemoveDeletedTableFromTablesNodes()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable unchangedDBTable = dbDatabase.CreateUnchangedTable();
            DBTable addedDBTable = dbDatabase.CreateAddedTable();
            DBTable deletedDBTable = dbDatabase.CreateDeletedTable();
            DBTable updatedDBTable = dbDatabase.CreateUpdatedTable();

            DatabaseInfoChangesControl changesControl = new DatabaseInfoChangesControl{Database = dbDatabase};

            ITreeView treeView = changesControl.TreeViewController.TreeView;
            ITreeNode tableInfosNode = treeView.Nodes[0].Nodes[0];
            ICheckBox checkbox = (ICheckBox)changesControl.FilterPanel.Controls[2];
            ITreeNodeCollection treeNodeCollection = tableInfosNode.Nodes;
            //-------------Assert Preconditions -------------
            Assert.AreEqual("Removed", checkbox.Text);
            Assert.AreEqual(true, checkbox.Checked);
            Assert.AreEqual(4, tableInfosNode.Nodes.Count);

            treeNodeCollection.AssertContainsTable(deletedDBTable);
            //---------------Execute Test ----------------------
            checkbox.Checked = false;
            //---------------Test Result -----------------------
            Assert.AreEqual(3, tableInfosNode.Nodes.Count);
            treeNodeCollection.AssertNotContainsTable(deletedDBTable);
        }

        [Test]
        public void Test_FilterUpdatedIsUnchecked_ShouldRemoveUpdatedFromTablesNodes()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable unchangedDBTable = dbDatabase.CreateUnchangedTable();
            DBTable addedDBTable = dbDatabase.CreateAddedTable();
            DBTable deletedDBTable = dbDatabase.CreateDeletedTable();
            DBTable updatedDBTable = dbDatabase.CreateUpdatedTable();
          
            
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl{Database = dbDatabase};
            ITreeView treeView = databaseInfoChangesControl.TreeViewController.TreeView;
            ITreeNode tableInfosNode = treeView.Nodes[0].Nodes[0];
            ICheckBox checkbox = (ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[3];
            ITreeNodeCollection treeNodeCollection = tableInfosNode.Nodes;
            //-------------Assert Preconditions -------------
            Assert.AreEqual("Updated", checkbox.Text);
            Assert.AreEqual(true, checkbox.Checked);
            Assert.AreEqual(4, tableInfosNode.Nodes.Count);
            treeNodeCollection.AssertContainsTable(updatedDBTable);
            //---------------Execute Test ----------------------
            checkbox.Checked = false;
            //---------------Test Result -----------------------
            Assert.AreEqual(3, tableInfosNode.Nodes.Count);
            treeNodeCollection.AssertNotContainsTable(updatedDBTable);
        }



        [Test]
        public void Test_Filter_UncheckAll()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable unchangedDBTable = new DBTable("UnchangedTable") { PendingChangeType = ChangeType.None };
            dbDatabase.Tables.Add(unchangedDBTable);
            DBTable addedDBTable = new DBTable("AddedTable") { PendingChangeType = ChangeType.Add };
            dbDatabase.Tables.Add(addedDBTable);
            DBTable deletedDBTable = new DBTable("DeletedTable") { PendingChangeType = ChangeType.Delete };
            dbDatabase.Tables.Add(deletedDBTable);
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(updatedDBTable);
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeView treeView = databaseInfoChangesControl.TreeViewController.TreeView;
            ITreeNode tableInfosNode = treeView.Nodes[0].Nodes[0];
            ICheckBox checkbox = (ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[0];
            ICheckBox checkbox2 = (ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[1];
            ICheckBox checkbox3 = (ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[2];
            ICheckBox checkbox4 = (ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[3];
            //-------------Assert Preconditions -------------
            Assert.AreEqual(4, tableInfosNode.Nodes.Count);
            //---------------Execute Test ----------------------
            checkbox.Checked = false;
            checkbox2.Checked = false;
            checkbox3.Checked = false;
            checkbox4.Checked = false;
            //---------------Test Result -----------------------
            Assert.AreEqual(0, tableInfosNode.Nodes.Count);
        }

        [Test]
        public void Test_Filter_WithChildren_AddedOnly()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(updatedDBTable);
            DBTableBuilder dbTableBuilder = new DBTableBuilder(updatedDBTable);
            dbTableBuilder.AddColumn("AddedColumn").PendingChangeType = ChangeType.Add;
            dbTableBuilder.AddColumn("UpdatedColumn").PendingChangeType = ChangeType.Update;

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeView treeView = databaseInfoChangesControl.TreeViewController.TreeView;
            ITreeNode tablesNode = treeView.Nodes[0].Nodes[0];
            ITreeNode tableColumnsNode = tablesNode.Nodes[0].Nodes[0];
            //-------------Assert Preconditions -------------
            Assert.AreEqual("Tables", tablesNode.Text);
            Assert.AreEqual(1, tablesNode.Nodes.Count);
            Assert.AreEqual("Columns", tableColumnsNode.Text);
            Assert.AreEqual(2, tableColumnsNode.Nodes.Count);
            //---------------Execute Test ----------------------
            ((ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[0]).Checked = false;
            ((ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[2]).Checked = false;
            ((ICheckBox)databaseInfoChangesControl.FilterPanel.Controls[3]).Checked = false;
            //---------------Test Result -----------------------
            Assert.AreEqual(1, tablesNode.Nodes.Count);
            Assert.AreEqual(1, tableColumnsNode.Nodes.Count);
            Assert.AreEqual(updatedDBTable, tablesNode.Nodes[0].Tag);
            Assert.AreEqual(updatedDBTable, tablesNode.Nodes[0].Tag);
        }


        [Test]
        public void Test_SetupNode_ApprovedIsFalse()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable updatedDBTable = new DBTable("UpdatedTable")
                                         {PendingChangeType = ChangeType.Update, Approved = false };
            dbDatabase.Tables.Add(updatedDBTable);
            
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
            // ITreeView treeView = controller.TreeView;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode node = controller.GetBusinessObjectTreeNode(updatedDBTable);
            Assert.IsFalse(node.Checked);
        }



        [Test]
        public void Test_SetupNode_ApprovedIsTrue()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable updatedDBTable = new DBTable("UpdatedTable")
                                         {PendingChangeType = ChangeType.Update, Approved = true };
            dbDatabase.Tables.Add(updatedDBTable);
            
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
          // ITreeView treeView = controller.TreeView;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode node = controller.GetBusinessObjectTreeNode(updatedDBTable);
            Assert.IsTrue(node.Checked);
        }

        [Test]
        public void Test_NodeCheckChanged_ToTrue_ShouldUpdateApproved()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update, Approved = false };
            dbDatabase.Tables.Add(updatedDBTable);
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
        //    ITreeView treeView = controller.TreeView;
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeNode node = controller.GetBusinessObjectTreeNode(updatedDBTable);
            //---------------Assert Precondition----------------
            Assert.IsFalse(node.Checked);
            Assert.IsFalse(updatedDBTable.PendingChangeApproved);
            //---------------Execute Test ----------------------
            node.Checked = true;
            //---------------Test Result -----------------------
            Assert.IsTrue(node.Checked);
            Assert.IsTrue(updatedDBTable.PendingChangeApproved);
        }

        [Test]
        public void Test_NodeCheckChanged_ToFalse_ShouldUpdateApproved()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update, Approved = true };
            dbDatabase.Tables.Add(updatedDBTable);
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
           // ITreeView treeView = controller.TreeView;
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeNode node = controller.GetBusinessObjectTreeNode(updatedDBTable);
            //---------------Assert Precondition----------------
            Assert.IsTrue(node.Checked);
            Assert.IsTrue(updatedDBTable.PendingChangeApproved);
            //---------------Execute Test ----------------------
            node.Checked = false;
            //---------------Test Result -----------------------
            Assert.IsFalse(node.Checked);
            Assert.IsFalse(updatedDBTable.PendingChangeApproved);
        }

        [Test]
        public void Test_SetupNode_ForRelationshipNode_WhenChildNodeApprovedIsTrue_ShouldStillBeFalse()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update, Approved = true };
            dbDatabase.Tables.Add(updatedDBTable);

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
           // ITreeView treeView = controller.TreeView;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.Database = dbDatabase;
            //---------------Test Result -----------------------
            ITreeNode tableNode = controller.GetBusinessObjectTreeNode(updatedDBTable);
            ITreeNode tablesRelationshipNode = tableNode.Parent;
            Assert.AreEqual("Tables", tablesRelationshipNode.Text, "(Precondition)Should be the correct node");
            Assert.IsFalse(tablesRelationshipNode.Checked);
        }

        [Test]
        public void Test_RelationshipNode_WhenCheckChanged_ToTrue_ShouldDoNothing()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update, Approved = false };
            dbDatabase.Tables.Add(updatedDBTable);
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
            //ITreeView treeView = controller.TreeView;
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeNode tableNode = controller.GetBusinessObjectTreeNode(updatedDBTable);
            ITreeNode tablesRelationshipNode = tableNode.Parent;
            //---------------Assert Precondition----------------
            Assert.AreEqual("Tables", tablesRelationshipNode.Text);
            Assert.IsFalse(tablesRelationshipNode.Checked);
            Assert.IsFalse(updatedDBTable.PendingChangeApproved);
            //---------------Execute Test ----------------------
            tablesRelationshipNode.Checked = true;
            //---------------Test Result -----------------------
            Assert.IsFalse(tablesRelationshipNode.Checked);
            Assert.IsFalse(updatedDBTable.PendingChangeApproved);
        }

        [Test]
        public void Test_RelationshipNode_WhenCheckChanged_ToFalse_ShouldDoNothing()

        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update, Approved = true };
            dbDatabase.Tables.Add(updatedDBTable);
            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
            //ITreeView treeView = controller.TreeView;
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeNode tableNode = controller.GetBusinessObjectTreeNode(updatedDBTable);
            ITreeNode tablesRelationshipNode = tableNode.Parent;
            //---------------Assert Precondition----------------
            Assert.AreEqual("Tables", tablesRelationshipNode.Text);
            Assert.IsFalse(tablesRelationshipNode.Checked);
            Assert.IsTrue(updatedDBTable.PendingChangeApproved);
            //---------------Execute Test ----------------------
            tablesRelationshipNode.Checked = false;
            //---------------Test Result -----------------------
            Assert.IsFalse(tablesRelationshipNode.Checked);
            Assert.IsTrue(updatedDBTable.PendingChangeApproved);
        }


        [Test]
        public void Test_CollapseButtonClick_WhenExpanded_ShouldCollapseAllTableNodes_AndNotCollapseAllNodesHigherInTheTree()
        {
            //---------------Set up test pack-------------------
            var dbDatabase = TestUtilsDBDatabase.GetTestFactory()
                .WithValue(database1 => database1.StoredByReverseEngineering, null)
                .WithOne(database => database.Tables)
                .CreateValidBusinessObject();

            DBTable table = dbDatabase.Tables[0];

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeNode tableNode = controller.GetBusinessObjectTreeNode(table);
            ITreeNode tablesRelationshipNode = tableNode.Parent;
            //---------------Assert Precondition----------------
            Assert.IsTrue(tableNode.IsExpanded);
            Assert.IsTrue(tablesRelationshipNode.IsExpanded);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.CollapseButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.IsFalse(tableNode.IsExpanded);
            Assert.IsTrue(tablesRelationshipNode.IsExpanded);
        }

        [Test]
        public void Test_CollapseButtonClick_WhenExpanded_ShouldCollapseAllViewNodes_AndNotCollapseAllNodesHigherInTheTree()
        {
            //---------------Set up test pack-------------------
            var dbDatabase = TestUtilsDBDatabase.GetTestFactory()
                .WithValue(database1 => database1.StoredByReverseEngineering, null)
                .WithOne(database => database.Views)
                .CreateValidBusinessObject();

            DBView view = dbDatabase.Views[0];

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
            databaseInfoChangesControl.Database = dbDatabase;
            ITreeNode viewNode = controller.GetBusinessObjectTreeNode(view);
            ITreeNode viewRelationshipNode = viewNode.Parent;
            //---------------Assert Precondition----------------
            Assert.IsTrue(viewNode.IsExpanded);
            Assert.IsTrue(viewRelationshipNode.IsExpanded);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.CollapseButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.IsFalse(viewNode.IsExpanded);
            Assert.IsTrue(viewRelationshipNode.IsExpanded);
        }


        [Test]
        public void Test_ExpandButtonClick_WhenCollapsed_ShouldExpandToLowestLevelNodes()
        {
            //---------------Set up test pack-------------------
            var dbDatabase = TestUtilsDBDatabase.GetTestFactory()
                .WithValue(database1 => database1.StoredByReverseEngineering, null)
                .WithOne(database => database.Tables)
                .CreateValidBusinessObject();

            DatabaseInfoChangesControl databaseInfoChangesControl = new DatabaseInfoChangesControl();
            TreeViewController controller = databaseInfoChangesControl.TreeViewController;
            databaseInfoChangesControl.Database = dbDatabase;
            IBusinessObject root = controller.RootNodeBusinessObject;
            ITreeNode rootNode = controller.GetBusinessObjectTreeNode(root);
            rootNode.Collapse();
            
            //---------------Assert Precondition----------------
            Assert.IsFalse(rootNode.IsExpanded);
            //---------------Execute Test ----------------------
            databaseInfoChangesControl.ExpandButton.PerformClick();
            //Need to call this again due to issues with refreshing in test mode.
            rootNode = controller.GetBusinessObjectTreeNode(root);
            //---------------Test Result -----------------------
            rootNode.AssertAllNodesAreExpanded();
        }

        #region Cascade PendingChangesApproved Select Checkboxes
        /// <summary>
        /// Bug #878
        ///ReverseEngineer from DB: Cascade Selection down
        ///Added by Frits Steyn 5 days ago. Updated 1 day ago. 

        ///Status: New Start: 2010-09-17 
        ///Priority: Normal Due date:  
        ///Assigned to: Andrew Russell % Done:  
        ///0%
 
        ///Category: Reverse Engineering From DB Spent time: - 
        ///Target version: 3.1 

        ///--------------------------------------------------------------------------------
        ///Description

        ///In the import from DB Tree.
        ///Import once Import changes into the system.
        ///The already existing objects have PendingChangesApproved = false.
        ///Have a child object that is edited e.g. removed a PrimaryKeyColumn
        ///The child will be PendingChangesApproved = false
        ///If Select Table for import then the PrimaryKey and the PrimaryKeyColumn should be selected as a downward cascade.
        ///I.e. If select the Table then all changes on that table should be selected as a cascade down.
        /// </summary>
        [Test]
        public void Test_SelectTableCheckBox_WithCheck_ShouldCascadeToChildrenWithChangeType_Update()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.CreateUpdatedTable();

            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            //changesControl.TreeViewController.TreeView.ExpandAll();
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBColumn updatedColumn = dbTableBuilder.AddColumn("UpdatedColumn");
            updatedColumn.PendingChangeType = ChangeType.Update;

            ITreeNode updatedTableNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(dbTable);
            updatedTableNode.Checked = false;
            ITreeNode updatedColumnNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(updatedColumn);
            updatedColumnNode.Checked = false;

            //---------------Assert Precondition----------------
            Assert.That(updatedTableNode.Checked, Is.False);
            Assert.That(updatedColumnNode.Checked,Is.False);
            //---------------Execute Test ----------------------
            updatedTableNode.Checked = true;
            //---------------Test Result -----------------------
            Assert.That(updatedTableNode.Checked, Is.True,"Table Node has been not been set to true");
            Assert.That(dbTable.PendingChangeApproved, Is.True, "updatedDBTable has not had PendingChangeApproved");
            Assert.That(updatedColumnNode.Checked, Is.True, "Cascade true to child node failed");
            Assert.That(updatedColumn.PendingChangeApproved, Is.True, "updatedColumn has not had PendingChangeApproved");
            //Assert.Fail("Not Yet Implemented");
        }

        [Test]
        public void Test_SelectTableCheckBox_WithCheck_ShouldCascadeToChildrenWithChangeType_Add()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.CreateAddedTable();

            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBColumn updatedColumn = dbTableBuilder.AddColumn("AddedColumn");
            updatedColumn.PendingChangeType = ChangeType.Add;

            ITreeNode updatedTableNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(dbTable);
            updatedTableNode.Checked = false;
            ITreeNode updatedColumnNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(updatedColumn);
            updatedColumnNode.Checked = false;

            //---------------Assert Precondition----------------
            Assert.That(updatedTableNode.Checked, Is.False);
            Assert.That(updatedColumnNode.Checked, Is.False);
            //---------------Execute Test ----------------------
            updatedTableNode.Checked = true;
            //---------------Test Result -----------------------
            Assert.That(updatedTableNode.Checked, Is.True, "Table Node has been not been set to true");
            Assert.That(dbTable.PendingChangeApproved, Is.True, "updatedDBTable has not had PendingChangeApproved");
            Assert.That(updatedColumnNode.Checked, Is.True, "Cascade true to child node failed");
            Assert.That(updatedColumn.PendingChangeApproved, Is.True, "updatedColumn has not had PendingChangeApproved");
        }


        [Test]
        public void Test_SelectTableCheckBox_ShouldNotCheckColumnsNotOfType_IMergableBO()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase
                                    {
                                        PendingChangeApproved = false,
                                        PendingChangeType = ChangeType.Add
                                    };
            DBTable dbTable = new DBTable
                              {
                                   PendingChangeApproved = false,
                                   PendingChangeType = ChangeType.Add
                              };
            dbDatabase.Tables.Add(dbTable);
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            ITreeNode dbNode = changesControl.TreeViewController.TreeView.Nodes[0];
            ITreeNode tablesNode = changesControl.TreeViewController.TreeView.Nodes[0].Nodes[0];
            ITreeNode dbTableNode = changesControl.TreeViewController.TreeView.Nodes[0].Nodes[0].Nodes[0];

            //---------------Assert Precondition----------------
            IMergableBo bo = tablesNode.Tag as IMergableBo;
            Assert.That(bo, Is.Null);
            Assert.That(tablesNode.Checked, Is.False);


            //---------------Execute Test ----------------------
            dbNode.Checked = true;
            //---------------Test Result -----------------------

            IMergableBo expectedBo = tablesNode.Tag as IMergableBo;
            Assert.That(expectedBo, Is.Null);
            Assert.That(tablesNode.Checked, Is.False);
        }


        [Ignore("REASON")] //TODO Andrew Russell 23 Sep 2010: Ignored Test - REASON
        [Test]
        public void Test_SelectTableCheckBox_ShouldCascadeToUCProp()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.CreateUpdatedTable();
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            dbTableBuilder.AddUniqueKeyColumn("UniqueKeyColumn");
/*            DBColumn columnWithUConstraing = dbTableBuilder.AddUniqueKeyColumn("UniqueKeyColumn");
            columnWithUConstraing.PendingChangeType = ChangeType.Update;*/
            DBKey uniqueKey = dbTable.Keys[0];
            DBKeyColumn keyColumn = uniqueKey.KeyColumns[0];
            uniqueKey.PendingChangeType = ChangeType.Update;
            keyColumn.PendingChangeType = ChangeType.Update;
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            changesControl.TreeViewController.TreeView.ExpandAll();


            ITreeNode tableNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(dbTable);
            tableNode.Checked = false;
            ITreeNode uniqueKeyNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(uniqueKey);
            uniqueKeyNode.Checked = false;
            ITreeNode uniqueKeyColumnNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(keyColumn);
            uniqueKeyColumnNode.Checked = false;
            //---------------Assert Precondition----------------

            Assert.That(uniqueKey.PendingChangeType, Is.Not.EqualTo(ChangeType.None));
            Assert.That(keyColumn.PendingChangeType, Is.Not.EqualTo(ChangeType.None));

            Assert.That(tableNode.Checked, Is.False);
            Assert.That(uniqueKeyColumnNode.Checked, Is.False);
            Assert.That(uniqueKeyNode.Checked, Is.False);

            //---------------Execute Test ----------------------
            tableNode.Checked = true;
            
            //---------------Test Result -----------------------
            
            Assert.That(tableNode.Checked, Is.True, "Table Node has been not been set to true");
            Assert.That(uniqueKeyNode.Checked, Is.True, "Cascade true to Unique Key node failed");
            Assert.That(uniqueKeyColumnNode.Checked, Is.True, "Cascade true to Unique Key Column failed");
            //Assert.Fail("Not Yet Implemented");
        }

        [Ignore("REASON")] //TODO Andrew Russell 23 Sep 2010: Ignored Test - REASON
        [Test]
        public void Test_CheckTableTrue_ShouldNotCheckColumnsThatHavePendingChangeTypeNone()
        {
            //---------------Set up test pack-------------------
            
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------

            //---------------Test Result -----------------------
            Assert.Fail("Not Yet Implemented");
        }
        [Ignore("REASON")] //TODO Andrew Russell 23 Sep 2010: Ignored Test - REASON
        [Test]
        public void Test_WhenUncheckTable_ShouldUncheckAllChildren()
        {
            //---------------Set up test pack-------------------
            
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------

            //---------------Test Result -----------------------
            Assert.Fail("Not Yet Implemented");
        }


        [Test]
        public void Test_CheckTableNodeTrue_ShouldSetTablePendingChangeApproved_True()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.CreateUpdatedTable();
            dbTable.PendingChangeApproved = false;
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            changesControl.TreeViewController.TreeView.ExpandAll();
            ITreeNode tableNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(dbTable);
           // uniqueKeyColumnNode.Checked = false;
            //---------------Assert Precondition----------------
            Assert.IsFalse(dbTable.PendingChangeApproved, "Pre: Should not be approved");
            Assert.IsFalse(tableNode.Checked, "Pre: Should not be checked");
            //---------------Execute Test ----------------------
            tableNode.Checked = true;
            //---------------Test Result -----------------------
            Assert.IsTrue(dbTable.PendingChangeApproved, "Post: Should be approved");
            Assert.IsTrue(tableNode.Checked, "Post: Should be checked");
        }

        [Test]
        public void Test_CheckTableFalse_ShouldSetTablePendingChangeApproved_False()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.CreateUpdatedTable();

            dbTable.PendingChangeApproved = true;
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            changesControl.TreeViewController.TreeView.ExpandAll();
            ITreeNode tableNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(dbTable);
           // uniqueKeyColumnNode.Checked = false;
            //---------------Assert Precondition----------------
            Assert.IsTrue(dbTable.PendingChangeApproved, "Pre: Should be approved");
            Assert.IsTrue(tableNode.Checked, "Pre: Should be checked");
            //---------------Execute Test ----------------------
            tableNode.Checked = false;
            //---------------Test Result -----------------------
            Assert.IsFalse(dbTable.PendingChangeApproved, "Post: Should not be approved");
            Assert.IsFalse(tableNode.Checked, "Post: Should not be checked");
        }

        [Test]
        public void Test_CheckColumnNodeTrue_ShouldSetColumnPendingChangeApproved_True()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBColumn column = GetColumnWithTable(dbDatabase);
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            changesControl.TreeViewController.TreeView.ExpandAll();
            ITreeNode columnNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(column);
           // uniqueKeyColumnNode.Checked = false;
            //---------------Assert Precondition----------------
            Assert.IsFalse(column.PendingChangeApproved, "Pre: Should not be approved");
            Assert.IsFalse(columnNode.Checked, "Pre: Should not be checked");
            //---------------Execute Test ----------------------
            columnNode.Checked = true;
            //---------------Test Result -----------------------
            Assert.IsTrue(columnNode.Checked, "Post: Should be checked");
            Assert.IsTrue(column.PendingChangeApproved, "Post: Should be approved");
        }
        [Test]
        public void Test_CheckTableNodeTrue_WhenHasColumn_ShouldSetColumnPendingChangeApproved_True()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBColumn column = GetColumnWithTable(dbDatabase);
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            changesControl.TreeViewController.TreeView.ExpandAll();
            ITreeNode columnNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(column);
           // uniqueKeyColumnNode.Checked = false;
            //---------------Assert Precondition----------------
            Assert.IsFalse(column.PendingChangeApproved, "Pre: Should not be approved");
            Assert.IsFalse(columnNode.Checked, "Pre: Should not be checked");
            //---------------Execute Test ----------------------
            columnNode.Checked = true;
            //---------------Test Result -----------------------
            Assert.IsTrue(column.PendingChangeApproved, "Post: Should be approved");
            Assert.IsTrue(columnNode.Checked, "Post: Should be checked");
        }

        [Test]
        public void Test_CheckTableFalse_WhenHasColumn_ShouldSetColumnPendingChangeApproved_False()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.CreateUpdatedTable();
            dbTable.PendingChangeApproved = true;
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            changesControl.TreeViewController.TreeView.ExpandAll();
            ITreeNode tableNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(dbTable);
            changesControl.TreeViewController.TreeView.ExpandAll();
           // uniqueKeyColumnNode.Checked = false;
            //---------------Assert Precondition----------------
            Assert.IsTrue(dbTable.PendingChangeApproved, "Pre: Should not be approved");
            Assert.IsTrue(tableNode.Checked, "Pre: Should not be checked");
            //---------------Execute Test ----------------------
            tableNode.Checked = false;
            //---------------Test Result -----------------------
            Assert.IsFalse(dbTable.PendingChangeApproved, "Post: Should be approved");
            Assert.IsFalse(tableNode.Checked, "Post: Should be checked");
        }

        [Test]
        public void Test_SetColumnPendingChangeApproved_True_ShouldSetCheckBoxCheckedTrue()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBColumn column = GetColumnWithTable(dbDatabase);
            var changesControl = new DatabaseInfoChangesControl { Database = dbDatabase };
            changesControl.TreeViewController.TreeView.ExpandAll();
            ITreeNode columnNode = changesControl.TreeViewController.GetBusinessObjectTreeNode(column);
            // uniqueKeyColumnNode.Checked = false;
            //---------------Assert Precondition----------------
            Assert.IsFalse(column.PendingChangeApproved, "Pre: Should not be approved");
            Assert.IsFalse(columnNode.Checked, "Pre: Should not be checked");
            //---------------Execute Test ----------------------
            column.PendingChangeApproved = true;
            //---------------Test Result -----------------------
            Assert.IsTrue(columnNode.Checked, "Post: Should be checked");
            Assert.IsTrue(column.PendingChangeApproved, "Post: Should be approved");
        }
        private DBColumn GetColumn(DBTable dbTable)
        {
            DBTableBuilder dbTableBuilder = new DBTableBuilder(dbTable);
            DBColumn column = dbTableBuilder.AddColumn("Column");
            column.PendingChangeApproved = false;
            column.PendingChangeType = ChangeType.Delete;
            return column;
        }

        private DBColumn GetColumnWithTable(DBDatabase dbDatabase)
        {
            DBTable dbTable = dbDatabase.CreateUpdatedTable();
            return GetColumn(dbTable);
        }

        #endregion

        #region Update TreeView Checkboxes

        [Test]
        public void Test_Construct_DatabaseIfoChangesControlSpy()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DatabaseInfoChangesControlSpy spy = new DatabaseInfoChangesControlSpy();

            //---------------Test Result -----------------------
            Assert.That(spy, Is.Not.Null);
        }

        [Test]
        public void Test_CallUpdateTreeViewCheckBoxes_WithTrue_ShouldCheck_Node()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DatabaseInfoChangesControlSpy spy = new DatabaseInfoChangesControlSpy {Database = dbDatabase};
            spy.TreeViewController.TreeView.ExpandAll();
            //-------------Assert Preconditions -------------
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            //---------------Execute Test ----------------------
            spy.CallUpdateTreeViewCheckboxes(spy.TreeViewController.TreeView.Nodes[0],true);
            //---------------Test Result -----------------------
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Checked,Is.True);
        }


        [Test]
        public void Test_CallUpdateTreeViewCheckBoxes_WithFalse_ShouldUnCheck_Node()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DatabaseInfoChangesControlSpy spy = new DatabaseInfoChangesControlSpy { Database = dbDatabase };
            spy.TreeViewController.TreeView.ExpandAll();
            //-------------Assert Preconditions -------------
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            //---------------Execute Test ----------------------
            spy.CallUpdateTreeViewCheckboxes(spy.TreeViewController.TreeView.Nodes[0], false);
            //---------------Test Result -----------------------
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Checked, Is.False);
        }


        [Test]
        public void Test_CallUpdateTreeViewCheckBoxes_WithTrue_Should_CheckCurrentNodeAndChildren_Nodes()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = new DBTable("mytable");
            dbDatabase.Tables.Add(dbTable);

            DatabaseInfoChangesControlSpy spy = new DatabaseInfoChangesControlSpy { Database = dbDatabase };
            //-------------Assert Preconditions -------------
            // Database
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            // Tables and Views (Dummy Nodes)
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Nodes.Count, Is.EqualTo(2));
            // Tables
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Nodes[0].Nodes.Count, Is.EqualTo(1));
            //---------------Execute Test ----------------------
            spy.CallUpdateTreeViewCheckboxes(spy.TreeViewController.TreeView.Nodes[0], true);
            //---------------Test Result -----------------------
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Checked, Is.True);
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Nodes[0].Nodes[0].Checked, Is.True);
        }

        [Test]
        public void Test_CallUpdateTreeViewCheckBoxes_WithFalse_Should_UnCheckCurrentNodeAndChildrenNodes()
        {
            //---------------Set up test pack-------------------
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = new DBTable("mytable");
            dbDatabase.Tables.Add(dbTable);

            DatabaseInfoChangesControlSpy spy = new DatabaseInfoChangesControlSpy { Database = dbDatabase };
            //-------------Assert Preconditions -------------
            // Database
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            // Tables and Views (Dummy Nodes)
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Nodes.Count, Is.EqualTo(2));
            // Tables
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Nodes[0].Nodes.Count, Is.EqualTo(1));
            //---------------Execute Test ----------------------
            spy.CallUpdateTreeViewCheckboxes(spy.TreeViewController.TreeView.Nodes[0], false);
            //---------------Test Result -----------------------
            Assert.That(spy.TreeViewController.TreeView.Nodes.Count, Is.EqualTo(1));
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Checked, Is.False);
            Assert.That(spy.TreeViewController.TreeView.Nodes[0].Nodes[0].Nodes[0].Checked, Is.False);
        }

        #endregion

        #region Visible Prop


        [Test]
        public void Test_VisibleSetter_WhenSetFalse_DoesNotThrowExceptionInVisibleChangeEvent()
        {
            //---------------Set up test pack-------------------
            DatabaseInfoChangesControl control = new DatabaseInfoChangesControl();
            //---------------Assert Precondition----------------
            Assert.IsTrue(control.Visible);        
            //---------------Execute Test ----------------------
            control.Visible = false;
            //---------------Test Result -----------------------
            Assert.IsFalse(control.Visible);
        }

        [Test]
        public void Test_VisibleSetter_WhenSetTrue_DoesNotThrowExceptionInVisibleChangeEvent()
        {
            //---------------Set up test pack-------------------
            DatabaseInfoChangesControl control = new DatabaseInfoChangesControl();
            //---------------Assert Precondition----------------
            control.Visible = false; 
            Assert.IsFalse(control.Visible);
            //---------------Execute Test ----------------------
                control.Visible = true;
            //---------------Test Result -----------------------
            Assert.IsTrue(control.Visible);
        }


        #endregion


    }

    #region DatabaseIfoChangeControl Spy
    internal class DatabaseInfoChangesControlSpy : DatabaseInfoChangesControl
    {

        public void CallUpdateTreeViewCheckboxes(ITreeNode treeNode, bool check)
        {
            base.UpdateTreeViewCheckboxes(treeNode, check);
        }

    }

    #endregion


    #region ExtensionMethods

    internal static class TreeNodeAssertExtensions
    {
        internal static void AssertAllNodesAreExpanded(this ITreeNode node)
        {
            Assert.IsTrue(node.IsExpanded, "Node '" + node + "' should be expanded");
            foreach (ITreeNode childNode in node.Nodes)
            {
                AssertAllNodesAreExpanded(childNode);
            }
        }

        internal static void AssertNotContainsTable(this ITreeNodeCollection nodesCollection, DBTable table)
        {
            bool existsInCollection = nodesCollection.Cast<ITreeNode>().Any(node => node.Tag == table);
            Assert.IsFalse(existsInCollection, "The Table '" + table.TableName + " ' should not be present in the Nodes Collection");
        }
        internal static void AssertContainsTable(this ITreeNodeCollection nodesCollection, DBTable table)
        {
            bool existsInCollection = nodesCollection.Cast<ITreeNode>().Any(node => node.Tag == table);
            Assert.IsTrue(existsInCollection, "The Table '" + table.TableName + " ' should be present in the Nodes Collection");
        }
    }

    internal static class DBDatabaseExtensions
    {
        internal static DBTable CreateUpdatedTable(this DBDatabase dbDatabase)
        {
            DBTable updatedDBTable = new DBTable("UpdatedTable") { PendingChangeType = ChangeType.Update };
            dbDatabase.Tables.Add(updatedDBTable);
            return updatedDBTable;
        }

        internal static DBTable CreateDeletedTable(this DBDatabase dbDatabase)
        {
            return CreateTable(dbDatabase, "DeletedTable", ChangeType.Delete);
        }

        internal static DBTable CreateAddedTable(this DBDatabase dbDatabase)
        {
            return CreateTable(dbDatabase, "AddedTable", ChangeType.Add);

        }

        internal static DBTable CreateUnchangedTable(this DBDatabase dbDatabase)
        {
            return CreateTable(dbDatabase, "UnchangedTable", ChangeType.None);
        }

        private static DBTable CreateTable(DBDatabase dbDatabase, string tableName, ChangeType pendingChangeType)
        {
            DBTable unchangedDBTable = new DBTable(tableName) { PendingChangeType = pendingChangeType };
            dbDatabase.Tables.Add(unchangedDBTable);
            return unchangedDBTable;
        }

    }

    #endregion

    // ReSharper restore InconsistentNaming
}
